#ifndef _EDL_H_
#define _EDL_H_

#include "eds.h"

#define EDI_FUNC	1
#define EDI_ASRTV	2
#define EDI_LNP		3
#define EDI_MEMBERLNP	4
#define EDI_SEQUENTIAL	5
#define EDI_VECTOR	6
#define EDI_VECTOR1	7
#define EDI_COND	8
#define EDI_CNP		9
#define EDI_SET		10
#define EDI_XECREATE	11
#define EDI_XEDELETE	12
#define EDI_SUBENTITY	13
#define EDI_SAME	14
#define EDI_NOTSAME	15
#define EDI_NAME	16
#define EDI_CHILDCNT	17
#define EDI_ACTUATOR	18
#define EDI_EXIST	19
#define EDI_VECTORPLUS	20
#define EDI_VECTORMINUS	21
#define EDI_OWNER	22
#define EDI_FILE	23
#define EDI_LOGICALAND	24
#define EDI_LOGICALOR	25
#define EDI_HOMOSET	26
#define EDI_HOMOSETHAS	27
#define EDI_CALL	28
#define EDI_CALLONEWAY	29
#define EDI_ARGVAR	30
#define EDI_UIARG	31
#define EDI_UIVAR	32
#define EDI_WHILE	33
#define EDI_CASE	34
#define EDI_CASEVAR	35
#define EDI_CAST	36
#define EDI_REXEC	37
#define EDI_CS		38
#define EDI_BITWISEOR	39
#define EDI_CTXVALVAR	40
#define EDI_CNP1	41
#define EDI_MEMBER	42
#define EDI_XECREATE_SA	43
#define EDI_XECREATE_FUNC	44

#define EDI_EOF		EDI_XECREATE_FUNC

#define	BASEFUNC_EQUAL		1
#define	BASEFUNC_NOTEQUAL	2
#define	BASEFUNC_PLUS		3
#define	BASEFUNC_MINUS		4
#define BASEFUNC_GREATERTHAN	5
#define BASEFUNC_LESSTHAN	6
#define BASEFUNC_GREATEREQUAL	7
#define BASEFUNC_LESSEQUAL	8
#define BASEFUNC_LOGICALNOT	9

#define EQUAL_FID		BASE_FUNC_FID(BASEFUNC_EQUAL)
#define	NOTEQUAL_FID		BASE_FUNC_FID(BASEFUNC_NOTEQUAL)
#define	PLUS_FID		BASE_FUNC_FID(BASEFUNC_PLUS)
#define	MINUS_FID		BASE_FUNC_FID(BASEFUNC_MINUS)
#define GREATERTHAN_FID		BASE_FUNC_FID(BASEFUNC_GREATERTHAN)
#define LESSTHAN_FID		BASE_FUNC_FID(BASEFUNC_LESSTHAN)
#define GREATEREQUAL_FID	BASE_FUNC_FID(BASEFUNC_GREATEREQUAL)
#define LESSEQUAL_FID		BASE_FUNC_FID(BASEFUNC_LESSEQUAL)
#define LOGICALNOT_FID		BASE_FUNC_FID(BASEFUNC_LOGICALNOT)

#define	FID_MASK		0xffffff
#define FID_BASEFLAG		0x800000

#define FUNC_ID(fid, sigid)	(((fid) << 8) | (sigid & 0xff))

#define FUNC_ID_TO_FID(funcid)		((eds_fid_t)(((funcid) >> 8) & FID_MASK))
#define FUNC_ID_TO_SIGID(funcid)	((funcid) & 0xff)

#define BASE_FUNC_FID(idx)	(idx)
#define FUNC_FID(idx)		(FID_BASEFLAG | (idx))

#define FID_TO_IDX(fid)		(((fid) & ~FID_BASEFLAG) & FID_MASK)
#define IS_BASEFUNC(fid)	(((fid) & FID_BASEFLAG) == 0)

ECM_EXPIMP srt_t	ST_EDEXPR;

typedef ECMBOOL (*edl_travfunc_t)(const sr_t *sr_edi, ecm_ptr_t ctx);

sr_t *build_named_func_edi(char *name, sr_t *sr_args, char **perrmsg);
sr_t *build_func_edi(int fid, ecm_uint32 nargs, ...);
sr_t *build_seq_edi(sr_t *sr_edis);
sr_t *build_LNP_edi(sr_t *sr_lnpath);
sr_t *build_memberLNP_edi(ECMBOOL passive, ECMBOOL is_ref, ecm_uint32 dollarcnt, sr_t *sr_lnpath);
sr_t *build_ArgVar_edi(ECMBOOL is_ref, ecm_uint32 idx, sr_t *sr_lnpath);
sr_t *build_UIArg_edi(char *ettstr);
sr_t *build_UIVar_edi(char *name, ECMBOOL multi);
sr_t *build_CtxValVar_edi(sr_t *sr);
sr_t *build_CALL_edi(sr_t *sr_target, sr_t *sr_args, char *ettstr);

ECM_INLINE sr_t *buildv_edi(int edi_type, int nargs, ...);

sr_t *build_lnpath(ECMBOOL passive, const char *LNP);

sr_t *edl_create_sr_from_ASR(char *name, sr_t *sr_srt, sr_t *sr_asrv, char **perrmsg);
sr_t *edl_create_sr_from_ASRT(const char *srtstr);

sr_t *edl_get_edexpr(const char *edstr, ecm_uint32 *perrlineno, char **perrmsg);
ECMBOOL edl_check_edexpr(const char *edstr, ecm_uint32 *perrlineno, char **perrmsg);
ECMBOOL edl_exec_edexpr(const sr_t *sr, const sr_t *sr_edexpr);
char *edl_sr_to_edexpr(const sr_t *sr_edexprs);
sr_t *edl_edexpr_to_bdexpr(const sr_t *sr, const sr_t *sr_edexpr);

sr_t *edl_exec_bdexpr(const sr_t *sr, const sr_t *sr_bdexpr);

void edl_traverse(const sr_t *sr_edexpr, edl_travfunc_t func, ecm_ptr_t ctx);

ECMBOOL edl_initialize(void);

#ifdef ECM_DEBUG
extern int	edldebug;
extern ECMBOOL	scanner_debug;
#endif

#endif
